using System;
using Sce.Pss.Core;
using Sce.Pss.Core.Graphics;
using Sce.Pss.Core.Imaging;
using Sce.Pss.Core.Environment;

namespace CResourceManager
{
	//----------------------
	// Sprite Class
	//----------------------
	
	public class CSprite : IDisposable
	{
		
		//----------------------
		// Variables
		//----------------------
		
			private VertexBuffer vertices;
			
			//Position
	    	private float positionX;
	    	private float positionY;
			private float positionZ;
			
			//Origin of sprite
	    	private float centerX;
	    	private float centerY;
			private float centerZ;
			
			//Angle
	    	private float angleX;
			private float angleY;
			private float angleZ;
			
			//Scale
	    	private float scaleX;
	    	private float scaleY;
			
			//Texture
	   		private Texture2D texture;
		
		//----------------------
		// ~~ Variables
		//----------------------
		
		
		//----------------------
		// Constructers
		//----------------------
		
		    // Construct Sprite from Texture2D (pos X, pos Y)
    		public CSprite(Texture2D texture, float positionX, float positionY)
    		{
				// Call Texture to set to Sprite
        		SetTexture(texture);
				
				// Set Position
        		PositionX = positionX;
        		PositionY = positionY;
        		PositionZ = 0.0f;
				
				// Set Origin
        		CenterX = texture.Width / 2;
        		CenterY = texture.Height / 2;
				CenterZ = 0.0f;
			
				// Set Angle
        		AngleX = 0.0f;
				AngleY = 0.0f;
				AngleZ = 0.0f;
			
				// Set Scale
        		ScaleX = 1.0f;
        		ScaleY = 1.0f;
    		}
			//~Construct Sprite from Texture2D (pos X, pos Y)
		
			// Construct Sprite from Texture2D (pos X, pos Y, pos Z)
    		public CSprite(Texture2D texture, float positionX, float positionY, float positionZ)
    		{
				// Call Texture to set to Sprite
        		SetTexture(texture);
				
				// Set Position
        		PositionX = positionX;
        		PositionY = positionY;
        		PositionZ = positionZ;
				
				// Set Origin
        		CenterX = texture.Width / 2;
        		CenterY = texture.Height / 2;
				CenterZ = 0.0f;
			
				// Set Angle
        		AngleX = 0.0f;
				AngleY = 0.0f;
				AngleZ = 0.0f;
			
				// Set Scale
        		ScaleX = 1.0f;
        		ScaleY = 1.0f;
    		}
			//~Construct Sprite from Texture2D (pos X, pos Y, pos Z)
		
		    // Construct Sprite from Texture2D (pos X, pos Y, angle Z, Scale)
		    public CSprite(Texture2D texture, float positionX, float positionY, float angle, float scale)
		    {
				// Call Texture to set to Sprite
		        SetTexture(texture);
		
				// Set Position
		        PositionX = positionX;
		        PositionY = positionY;
				PositionZ = 0.0f;
			
				// Set Origin
		        CenterX = texture.Width / 2;
		        CenterY = texture.Height / 2;
				CenterZ = 0.0f;
			
				// Set Angle
			    AngleX = 0.0f;
				AngleY = 0.0f;
		        AngleZ = angle;
		
				// Set Scale
		        ScaleX = scale;
		        ScaleY = scale;
		    }
			//~Construct Sprite from Texture2D (pos X, pos Y, angle Z, Scale)
		
			// Construct Sprite from Texture2D (pos X, pos Y, pos Z, angleX, angleY, angle Z, Scale)
			public CSprite(Texture2D texture, 
		               float positionX, float positionY, float positionZ, 
		               float angleX, float angleY, float angleZ, 
		               float scale)
			{
				// Call Texture to set to Sprite
		        SetTexture(texture);
		
				// Set Position
		        PositionX = positionX;
		        PositionY = positionY;
				PositionZ = positionZ;
			
				// Set Origin
		        CenterX = texture.Width / 2;
		        CenterY = texture.Height / 2;
				CenterZ = 0.0f;
			
				// Set Angle
			    AngleX = angleX;
				AngleY = angleY;
		        AngleZ = angleZ;
		
				// Set Scale
		        ScaleX = scale;
		        ScaleY = scale;
		    }
			//~Construct Sprite from Texture2D (pos X, pos Y, pos Z, angleX, angleY, angle Z, Scale)
		
		    // Construct Sprite from Texture2D (pos X, pos Y, center X, center Y, angle, Scale X, Scale Y)
		    /*public CSprite(Texture2D texture,
		                  float positionX, float positionY,
		                  float centerX, float centerY, float angle,
		                  float scaleX, float scaleY)
		    {
				// Call Texture to set to Sprite
		        SetTexture(texture);
		
				// Set Position
		        PositionX = positionX;
		        PositionY = positionY;
				PositionZ = 0.0f;
			
				// Set Origin
		        CenterX = centerX;
		        CenterY = centerY;
				CenterZ = 0.0f;
			
				// Set Angle
				AngleX = 0.0f;
				AngleY = 0.0f;
		        AngleZ = angle;
		
				// Set Scale
		        ScaleX = scaleX;
		        ScaleY = scaleY;
		    }
			//~Construct Sprite from Texture2D (pos X, pos Y, center X, center Y, angle, Scale X, Scale Y)*/
		
		    // Construct from text
		    public CSprite(string text, uint argb, Font font, int positionX, int positionY)
		    {
				// Get Width and Height from text
		        int width = font.GetTextWidth(text, 0, text.Length);
		        int height = font.Metrics.Height;
		
		        // clamp to max size
		        width = Math.Min( width, 2048 );
		
				// Create Image for Text
		        var image = new Image(ImageMode.Rgba,
					                  new ImageSize(width, height),
		                              new ImageColor(0, 0, 0, 0) );
		
		        image.DrawText(text,
		                       new ImageColor((int)((argb >> 16) & 0xff),
		                                      (int)((argb >> 8) & 0xff),
		                                      (int)((argb >> 0) & 0xff),
		                                      (int)((argb >> 24) & 0xff)),
		                       font, new ImagePosition(0, 0));
		
				// Convert Image to Texture
		        var texture = new Texture2D(width, height, false, PixelFormat.Rgba);
		        texture.SetPixels(0, image.ToBuffer(), 0, 0, width, height);
		        image.Dispose();
		
				// Call Texture to set to Sprite
		        SetTexture(texture);
		
				// Set Position
		        PositionX = positionX;
		        PositionY = positionY;
				PositionZ = 0.0f;
			
				// Set Origin
		        CenterX = texture.Width / 2;
		        CenterY = texture.Height / 2;
				CenterZ = 0.0f;
			
				// Set Angle
		        AngleX = 0.0f;
				AngleY = 0.0f;
				AngleZ = 0.0f;
			
				// Set Scale
		        ScaleX = 1.0f;
		        ScaleY = 1.0f;
		    }
			//~Construct from text
		
		//----------------------
		// ~~ Constructers
		//----------------------
		
		
		//----------------------
		// Geters & Setters
		//----------------------
		
			// Position
			public float PositionX			// X Axis Position
	    	{
	        	get {return positionX;}
	        	set {positionX = value;}
	    	}
			
	    	public float PositionY			// Y Axis Position
	    	{
	        	get {return positionY;}
	        	set {positionY = value;}
	    	}
			
			public float PositionZ			// Z Axis Position
	    	{
	        	get {return positionZ;}
	        	set {positionZ = value;}
	    	}
			//~Position
			
			
	    	// Origin of Sprite				
	    	public float CenterX			// X Axis Center
	    	{
	        	get {return centerX;}
	        	set {centerX = value;}
	    	}
			
	    	public float CenterY			// Y Axis Center
	    	{
	        	get {return centerY;}
	        	set {centerY = value;}
	    	}
			
			public float CenterZ			// Z Axis Center
	    	{
	        	get {return centerZ;}
	        	set {centerZ = value;}
	    	}
			//~Origin of Sprite	
			
			
	    	// Angle (Euler)
	    	public float AngleX				// X Angle
	    	{
	        	get {return angleX;}			
	        	set {angleX = value;}
	    	}
			
			public float AngleY				// Y Angle
	    	{
	        	get {return angleY;}			
	        	set {angleY = value;}
	    	}
			
			public float AngleZ				// Z Angle
	    	{
	        	get {return angleZ;}			
	        	set {angleZ = value;}
	    	}
			//~Angle (Euler)
		
		
			// Scale of sprite
	    	public float ScaleX				// X Scale
	    	{		
	        	get {return scaleX;}
	        	set {scaleX = value;}
	    	}
	
	    	public float ScaleY				// Y Scale
	    	{	
	        	get {return scaleY;}	
	        	set {scaleY = value;}
	    	}
			//~Scale of sprite
		
		
			// Other ( Vertices & Texture )
	    	public VertexBuffer Vertices
	    	{
	        	get {return vertices;}
	    	}
	
	    	public Texture2D Texture
	    	{
	        	get {return texture;}
	    	}
			//~Other ( Vertices & Texture )
		
		//----------------------
		// ~~ Geters & Setters
		//----------------------
		
		
		//----------------------
		// De alloc
		//----------------------
		
			public void Dispose()
	    	{
	        	vertices.Dispose();
	        	texture.Dispose();
	    	}
		
		//----------------------
		// ~~ De alloc
		//----------------------
		
		
		//----------------------
		// Create Texture & Transformation Matrix
		//----------------------
		
			// Create Sprite
			public void SetTexture(Texture2D texture)
	    	{
		        this.texture = texture.ShallowCopy();
		        float lelft = 0;
		        float top = 0;
		        float right = texture.Width;
		        float bottom = texture.Height;
		
				// Create vertex polygon for sprite
		        vertices = new VertexBuffer(4, VertexFormat.Float3, VertexFormat.Float2);
		        vertices.SetVertices(0, new float[]{lelft, top, 0,
		                                            right, top, 0,
		                                            right, bottom, 0,
		                                            lelft, bottom, 0});
		        vertices.SetVertices(1, new float[]{0.0f, 0.0f,
		                                            1.0f, 0.0f,
		                                            1.0f, 1.0f,
		                                            0.0f, 1.0f});
	    	}
	
			// Transformation Matrix
	    	public Matrix4 CreateModelMatrix()
	    	{
				// Center matrix
		        var centerMatrix = Matrix4.Translation(new Vector3(-centerX, -centerY, -centerZ));
				
				// Translate Matrix (position + center)
		        var transMatrix = Matrix4.Translation(new Vector3(positionX + centerX, positionY + centerY, positionZ + centerZ));
				
				// Rotattions Matrix
		        var rotMatrixZ = Matrix4.RotationZ((float)(angleZ / 180.0f * FMath.PI));
				var rotMatrixY = Matrix4.RotationY((float)(angleY / 180.0f * FMath.PI));
				var rotMatrixX = Matrix4.RotationX((float)(angleZ / 180.0f * FMath.PI));
				
				// Scale Matrix
		        var scaleMatrix = Matrix4.Scale(new Vector3(scaleX, scaleY, 1.0f));
		
				// Multiply Matrix for return Result Model Matrix
		        return transMatrix * rotMatrixX * rotMatrixY * rotMatrixZ * scaleMatrix * centerMatrix;
	    	}
		
		//----------------------
		// Create Texture & Transformation Matrix
		//----------------------
		
	}
	
	//----------------------
	// ~~ Sprite Class
	//----------------------
	
}
